﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Media3D; // PresentationCore Assembly must be added


namespace PlanetsAndOrbs
{
    public abstract class Sphere : Object3D
    {
        protected Vector3D  center_;
        protected Vector3D  vRadius_;
        protected double radius_;

        public Sphere(Vector3D center, double radius)
         {
            center_ = new Vector3D(center.X, center.Y, center.Z);
            radius_ = radius;
        }

        public override double distance(Vector3D origin, Vector3D ray)
        {
            Vector3D C = center_ - origin;

            // a^2 - 2*(v*c)*a + c^2 - r^2 = 0; find a
            // d = 4*((v*c)^2 - c^2 + r^2)
            double vc = Vector3D.DotProduct(ray, C);
            double c2 = C.LengthSquared;

            double d = vc * vc - c2 + radius_ * radius_; // *4 omitted
            if (d < 0)  // no intersecton
                return -1;

            // (-b - sqrt(d)) / 2a
            double sd = Math.Sqrt(d);

            // the 'nearest' point candidate
            double nearDist = vc - sd;
            if (nearDist >= 0)
                return nearDist;

            // we are inside the sphere, or it is behind us
            double farDist = vc + sd;
            if (farDist >= 0)
                return farDist; // we are inside the sphere

            return -1;
        }
    }
}
